package com.example.dbdoc.config;

import com.example.dbdoc.enums.DatabaseType;
import com.example.dbdoc.strategy.DatabaseMetadataStrategy;
import com.example.dbdoc.strategy.MySQLMetadataStrategy;
import com.example.dbdoc.strategy.PostgreSQLMetadataStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

/**
 * 数据库配置类
 * 
 * @author 系统生成
 * @version 1.0.0
 */
@Configuration
public class DatabaseConfig {
    
    private static final Logger logger = LoggerFactory.getLogger(DatabaseConfig.class);
    
    @Value("${database.url}")
    private String url;
    
    @Value("${database.username}")
    private String username;
    
    @Value("${database.password}")
    private String password;
    
    @Value("${database.driver-class-name:com.mysql.cj.jdbc.Driver}")
    private String driverClassName;
    
    @Value("${database.type:}")
    private String databaseTypeStr;
    
    /**
     * 配置数据源
     */
    @Bean
    public DataSource dataSource() {
        logger.info("正在配置数据源...");
        logger.info("数据库URL: {}", maskUrl(url));
        logger.info("用户名: {}", username);
        
        DatabaseType dbType = getDatabaseType();
        logger.info("数据库类型: {}", dbType.getDisplayName());
        
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        
        // 测试连接
        if (testConnection(dataSource)) {
            logger.info("数据库连接测试成功！");
        } else {
            logger.error("数据库连接测试失败！");
            logger.error("常见解决方案:");
            logger.error("1. 检查数据库服务是否启动");
            logger.error("2. 验证数据库URL、用户名和密码是否正确");
            logger.error("3. 确认网络连接是否正常");
            logger.error("4. 检查防火墙设置");
            logger.error("5. 验证数据库驱动版本是否兼容");
            throw new RuntimeException("无法连接到数据库，请检查配置参数和网络连接");
        }
        
        return dataSource;
    }
    
    /**
     * 配置数据库元数据查询策略
     */
    @Bean
    public DatabaseMetadataStrategy databaseMetadataStrategy() {
        DatabaseType dbType = getDatabaseType();
        logger.info("配置数据库元数据查询策略: {}", dbType.getDisplayName());
        
        switch (dbType) {
            case POSTGRESQL:
                return new PostgreSQLMetadataStrategy();
            case MYSQL:
            default:
                return new MySQLMetadataStrategy();
        }
    }
    
    /**
     * 获取数据库类型
     */
    public DatabaseType getDatabaseType() {
        // 优先使用配置的数据库类型
        if (databaseTypeStr != null && !databaseTypeStr.trim().isEmpty()) {
            try {
                return DatabaseType.valueOf(databaseTypeStr.toUpperCase());
            } catch (IllegalArgumentException e) {
                logger.warn("无效的数据库类型配置: {}, 将自动检测", databaseTypeStr);
            }
        }
        
        // 从URL自动检测
        DatabaseType typeFromUrl = DatabaseType.fromUrl(url);
        if (typeFromUrl != null) {
            return typeFromUrl;
        }
        
        // 从驱动类名检测
        return DatabaseType.fromDriverClassName(driverClassName);
    }
    
    /**
     * 配置JdbcTemplate
     */
    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
    
    /**
     * 测试数据库连接
     */
    public boolean testConnection(DataSource dataSource) {
        try (Connection connection = dataSource.getConnection()) {
            logger.debug("数据库连接测试 - 连接获取成功");
            
            // 测试基本查询
            boolean isValid = connection.isValid(5);
            logger.debug("数据库连接测试 - 连接有效性: {}", isValid);
            
            return isValid;
        } catch (SQLException e) {
            logger.error("数据库连接测试失败 - 错误代码: {}, 错误信息: {}", e.getErrorCode(), e.getMessage());
            logger.error("请检查以下配置项:");
            logger.error("  - 数据库URL: {}", maskUrl(url));
            logger.error("  - 用户名: {}", username);
            logger.error("  - 驱动类: {}", driverClassName);
            logger.error("  - 网络连接是否正常");
            logger.error("  - 数据库服务是否启动");
            logger.error("  - 用户权限是否正确");
            return false;
        }
    }
    
    /**
     * 掩码URL中的敏感信息
     */
    private String maskUrl(String url) {
        if (url == null) {
            return "null";
        }
        
        // 简单的URL掩码，隐藏密码部分
        if (url.contains("password=")) {
            return url.replaceAll("password=[^&]*", "password=***");
        }
        
        return url;
    }
    
    // Getter方法，供其他组件使用
    public String getUrl() {
        return url;
    }
    
    public String getUsername() {
        return username;
    }
    
    public String getDriverClassName() {
        return driverClassName;
    }
    
    /**
     * 获取数据库名称
     */
    public String getDatabaseName() {
        try {
            // 从URL中提取数据库名称
            if (url != null && url.contains("/")) {
                String[] parts = url.split("/");
                if (parts.length > 3) {
                    String dbPart = parts[3];
                    // 移除参数部分
                    if (dbPart.contains("?")) {
                        dbPart = dbPart.substring(0, dbPart.indexOf("?"));
                    }
                    return dbPart;
                }
            }
        } catch (Exception e) {
            logger.warn("无法从URL中提取数据库名称: {}", e.getMessage());
        }
        
        return "未知数据库";
    }
}